# -*- coding:utf-8 -*-
""" by 张润庶 """
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.remote.webdriver import WebElement
from functools import wraps
from testlib.file_path import CHROME_DRIVER
from testlib.utils import get_config
import time


class BasePage:
    """ 页面基类 """
    ROBOT_LIBRARY_SCOPE = 'GLOBAL'
    ROBOT_LIBRARY_VERSION = '0.1'

    driver = None

    def __init__(self):
        if BasePage.driver:
            self.driver = BasePage.driver
        else:
            chrome_options = Options()
            if get_config()['chrome']['headless']:
                chrome_options.add_argument("--headless")
            chrome_options.add_argument("--ignore-certificate-errors")
            self.driver = webdriver.Chrome(
                executable_path=CHROME_DRIVER,
                options=chrome_options)
            BasePage.driver = self.driver

    def element_length(self, jquery: str) -> int:
        """
            如果不存在此元素，则返回0，存在此元素，返回具体非0值
        :param jquery: 元素的 jquery 定位
        :return: 元素的长度
        """
        return self.driver.execute_script("return %s.length" % jquery)

    def element_is_exist(self, jquery: str, wait_time: int = 10) -> bool:
        """
            判断元素是否存在
        :param jquery: 元素的 jquery 定位
        :param wait_time: 等待时间
        :return: True or False
        """
        i = 0
        while i < wait_time:
            if self.element_length(jquery):
                time.sleep(0.5)
                return True
            i += 1
            time.sleep(1)
        return False

    def get_element(self, locator_type, locator_expression, timeout=30, wait_time=0, visible=True) -> WebElement:
        """ 获取元素 """
        if visible:
            element = WebDriverWait(self.driver, timeout).until(
                EC.visibility_of_element_located((locator_type, locator_expression)))
        else:
            element = WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((locator_type, locator_expression)))
        if wait_time:
            time.sleep(wait_time)
        print(element)
        return element

    def get_elements(self, locator_type, locator_expression, timeout=30, wait_time=0, visible=True) -> list:
        """ 获取可见的元素列表 """
        if visible:
            elements = WebDriverWait(self.driver, timeout).until(
                EC.visibility_of_all_elements_located((locator_type, locator_expression)))
        else:
            elements = WebDriverWait(self.driver, timeout).until(
                EC.presence_of_element_located((locator_type, locator_expression)))

        if wait_time:
            time.sleep(wait_time)

        return elements

    def input(self, locator_type, locator_expression, text, timeout=30, wait_time=0, visible=True):
        """ 清空文本框， 输入文本 """
        self.get_element(locator_type, locator_expression,
                         timeout=timeout, wait_time=wait_time, visible=visible).clear()
        self.get_element(locator_type, locator_expression,
                         timeout=timeout, wait_time=wait_time, visible=visible).send_keys(text)

    def click(self, locator_type, locator_expression, timeout=30, wait_time=0, visible=True):
        """ 点击元素 """
        if locator_type == 'jquery':
            if self.element_is_exist(locator_expression):
                self.driver.execute_script("%s.click()" % locator_expression)
            else:
                raise Exception("Cannot find this element: %s" % locator_expression)
        else:
            if visible:
                element = WebDriverWait(self.driver, timeout).until(
                    EC.element_to_be_clickable((locator_type, locator_expression)))  # type: WebElement
            else:
                element = WebDriverWait(self.driver, timeout).until(
                    EC.presence_of_element_located((locator_type, locator_expression)))  # type: WebElement
            if wait_time:
                time.sleep(wait_time)
            element.click()

    def close_and_switch_to_new_window(self):
        """ 关闭当前窗口，并切换到新的窗口 """
        self.driver.close()
        self.driver.switch_to.window(self.driver.window_handles[-1])


def i_frame(locator_type, frame_locator_expression):
    """
    提供一个进出frame的装饰器，被此装饰器装饰的函数会在指定的frame中执行，
    执行结束后跳出该指定的frame

    :param locator_type: 定位类型，比如id, xpath
    :param frame_locator_expression:  定位表达式
    :return:
    """
    def _i_frame(func):
        @wraps(func)
        def _inner_i_frame(*args, **kwargs):
            current_driver = args[0].driver
            try:
                WebDriverWait(current_driver, 10).until(
                    EC.frame_to_be_available_and_switch_to_it((locator_type, frame_locator_expression)))
                return func(*args, **kwargs)
            finally:
                current_driver.switch_to.parent_frame()
        return _inner_i_frame
    return _i_frame
